package com.doge.service.wx.coupon;

import com.alibaba.druid.sql.visitor.functions.If;
import com.alibaba.druid.util.StringUtils;
import com.doge.bean.base.BaseData;
import com.doge.bean.base.BaseParam;
import com.doge.bean.pojo.cart.Cart;
import com.doge.bean.pojo.cart.CartExample;
import com.doge.bean.pojo.coupon.Coupon;
import com.doge.bean.pojo.coupon.CouponExample;
import com.doge.bean.pojo.coupon.CouponUser;
import com.doge.bean.pojo.coupon.CouponUserExample;
import com.doge.bean.pojo.goods.Goods;
import com.doge.bean.pojo.goods.GoodsExample;
import com.doge.bean.vo.coupon.WxCouponCartVO;
import com.doge.bean.vo.coupon.WxListMyCouponVO;
import com.doge.exception.Param602Exception;
import com.doge.mapper.CartMapper;
import com.doge.mapper.CouponMapper;
import com.doge.mapper.CouponUserMapper;
import com.doge.mapper.GoodsMapper;
import com.doge.util.auth.GetSubject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.sql.Array;
import java.util.*;

/**
 * 微信商城前台有关的接口
 * Created By tian
 */
@Service
public class WxCouponServiceImpl implements WxCouponService{
    @Autowired
    CouponMapper couponMapper;
    @Autowired
    CartMapper cartMapper;
    @Autowired
    CouponUserMapper couponUserMapper;
    @Autowired
    GoodsMapper goodsMapper;

    /**
     * 在用户未登录的时候，在首页index看到的coupon优惠券专题，点击进去就可以查看优惠券列表
     * 如果用户点击某个优惠券，领取了优惠券，那么优惠券就存入到用户中心的优惠券里面，在coupon/mylist接口
     * @param baseParam 分页数据
     * @return 分页数据+couponList
     */
    @Override
    public BaseData listWxCoupons(BaseParam baseParam) {
        PageHelper.startPage(baseParam.getPage(),baseParam.getLimit());
        CouponExample couponExample = new CouponExample();
        CouponExample.Criteria criteria = couponExample.createCriteria();
        //查看优惠券是否过期
        List<Coupon> coupons = couponMapper.selectByExample(couponExample);
        for (Coupon coupon : coupons) {
            if (coupon.getEndTime()!=null && coupon.getEndTime().before(new Date())){
                coupon.setStatus((short) 1);
            }
        }
        //出现在首页的优惠券，删除状态=false，数量大于0，status处于可用状态（而不是下架，过期）
        criteria.andDeletedEqualTo(false).andTotalGreaterThanOrEqualTo(0).andStatusEqualTo((short) 0);
        List<Coupon> couponList= couponMapper.selectByExample(couponExample);

        PageInfo pageInfo = new PageInfo(couponList);
        long total = pageInfo.getTotal();
        int pages = pageInfo.getPages();
        BaseData data = BaseData.list(couponList, total);
        data.setLimit(baseParam.getLimit());
        data.setPage(baseParam.getPage());
        data.setPages(pages);
        return data;
    }

    /**
     * 在用户领取完优惠券，在个人中心里可以查看的优惠券
     * @param baseParam 分页数据
     * @param status 优惠券状态，0是可以用，1是过期，2是下架
     * @return 分页数据+couponList
     */
    @Override
    public BaseData listMyCoupon(BaseParam baseParam, Short status) {
        //获取当前用户是谁
        Integer userId = GetSubject.getUserId();
        PageHelper.startPage(baseParam.getPage(),baseParam.getLimit());
        CouponUserExample example = new CouponUserExample();
        CouponUserExample.Criteria criteria = example.createCriteria();
        if (!StringUtils.isEmpty(String.valueOf(status))){
            criteria.andDeletedEqualTo(false).andStatusEqualTo(status).andUserIdEqualTo(userId);
        }
        List<CouponUser> couponUsers= couponUserMapper.selectByExample(example);
        if (couponUsers.size()==0){
            return null;
        }
        List<WxListMyCouponVO> list = new ArrayList<>();
        List<Integer> couponIds = new ArrayList<>();
        Set<Integer> set = new HashSet<>();
        for (CouponUser coupon : couponUsers) {
            if (set.add(coupon.getCouponId())){
                couponIds.add(coupon.getCouponId());
            }
        }

        CouponExample couponExample = new CouponExample();
        CouponExample.Criteria couponCriteria = couponExample.createCriteria();
        couponCriteria.andIdIn(couponIds).andDeletedEqualTo(false);
        List<Coupon> coupons = couponMapper.selectByExample(couponExample);
        for (CouponUser couponUser : couponUsers) {
            WxListMyCouponVO vo = new WxListMyCouponVO();
            for (Coupon coupon : coupons) {
                Integer cid = couponUser.getCouponId();
                Integer id = coupon.getId();
                if(!cid.equals(id)){
                    continue;

                }
                vo.setName(coupon.getName());
                vo.setDesc(coupon.getDesc());
                vo.setMin(coupon.getMin());
                vo.setDiscount(coupon.getDiscount());
                vo.setId(couponUser.getId());
                vo.setCid(couponUser.getCouponId());
                vo.setStartTime(couponUser.getStartTime());
                vo.setEndTime(couponUser.getEndTime());
                vo.setAvailable(false);
                if(!StringUtils.isEmpty(coupon.getTag())){
                    vo.setTag(coupon.getTag());
                }
                break;
            }
            list.add(vo);
        }

        PageInfo pageInfo = new PageInfo(list);
        long total = pageInfo.getTotal();
        int pages = pageInfo.getPages();
        BaseData data = BaseData.list(list, total);
        data.setLimit(baseParam.getLimit());
        data.setPage(baseParam.getPage());
        data.setPages(pages);
        return data;
    }

    /**
     * 在商品页面中，点击立即购买，点击使用优惠券，进入选择优惠券的页面
     * 比较复杂，设计到购物车，userId用户，优惠券CouponId（用Coupon-User表连接起来）
     * @param cartId 购物车的id
     * @return 分页数据+couponList page =1,total=优惠券个数, pages=1,limit=有几个优惠券 没有分页
     */
    @Override
    public BaseData listCartCoupon(Integer cartId) {
        //通过购物车的userId和deleted确定现在购物车里都有什么商品，得到goods_Id的list
        //全局的userId, 当前用户是谁
        Integer userId = GetSubject.getUserId();
        CartExample cartExample = new CartExample();
        CartExample.Criteria cartCriteria = cartExample.createCriteria();
        cartCriteria.andDeletedEqualTo(false).andUserIdEqualTo(userId);
        List<Cart> carts = cartMapper.selectByExample(cartExample);
        //购物车里有什么商品 goodsIds
        List<Integer> goodsIdsCart = new ArrayList<>();
        for (Cart cart : carts) {
            Integer goodsId = cart.getGoodsId();
            goodsIdsCart.add(goodsId);
        }
        GoodsExample goodsExample = new GoodsExample();
        GoodsExample.Criteria goodsCriteria = goodsExample.createCriteria();
        if (goodsIdsCart.size()==0){
            return null;
        }
        goodsCriteria.andIdIn(goodsIdsCart);
        List<Goods> goods = goodsMapper.selectByExample(goodsExample);
        List<Integer> CategoryIdsCart = new ArrayList<>();
        for (Goods good : goods) {
            CategoryIdsCart.add(good.getCategoryId());
        }

        //这个goodsIds肯定不为空，除非购物车里东西为空，那这样也看不到下单的界面。立即购买，fastAdd也是一样的
        CouponUserExample couponUserExample = new CouponUserExample();
        CouponUserExample.Criteria couponUserCriteria = couponUserExample.createCriteria();
        couponUserCriteria.andDeletedEqualTo(false).andStatusEqualTo((short) 0).andUserIdEqualTo(userId);
        List<CouponUser> couponUsers = couponUserMapper.selectByExample(couponUserExample);
        //代表此人没有领过任何优惠券
        if (couponUsers.size()==0){
            return null;
        }
        List<Integer> couponIdList = new ArrayList<>();
        List<WxCouponCartVO> couponCartList = new ArrayList<>();

        //这个couponIdList是为了查询，couponExample删选条件而建立的
        for (CouponUser couponUser : couponUsers) {
            Integer couponId = couponUser.getCouponId();
            couponIdList.add(couponId);
        }
        //得到一堆couponIds，用这些couponIds去找coupons，去找一堆优惠券的详细信息（名字，描述，满减金额，最低消费...）
        CouponExample couponExample = new CouponExample();
        CouponExample.Criteria couponCriteria = couponExample.createCriteria();
        couponCriteria.andIdIn(couponIdList).andDeletedEqualTo(false);
        //查看优惠券是否过期，如果优惠券在购物的时刻过期，就更改优惠券的状态
        List<Coupon> coupons1 = couponMapper.selectByExample(couponExample);
        for (Coupon coupon : coupons1) {
            if (coupon.getEndTime()!=null && coupon.getEndTime().before(new Date())){
                coupon.setStatus((short) 1);
                couponMapper.updateByPrimaryKeySelective(coupon);
            }
        }
        couponExample.createCriteria().andStatusEqualTo((short) 0).andIdIn(couponIdList).andDeletedEqualTo(false);
        List<Coupon> coupons = couponMapper.selectByExample(couponExample);
        List<Coupon> couponList = new ArrayList<>();
        List<Integer> goodsValueList = new ArrayList<>();
        //现在已经查出来此人有什么可以用的优惠券
        for (Coupon coupon : coupons) {
            //全场通用类优惠券
            if (coupon.getGoodsType()==0){
                couponList.add(coupon);
            }
            //指定一堆category优惠券，goodsValue=categoryIds
            if (coupon.getGoodsType()==1){
                Integer[] goodsValue = coupon.getGoodsValue();
                goodsValueList.addAll(Arrays.asList(goodsValue));
                for (Integer categoryId : CategoryIdsCart) {
                    if (goodsValueList.contains(categoryId)){
                        couponList.add(coupon);
                    }
                }
            }
            //指定一堆商品优惠券,goodsValue=goodsIds
            if (coupon.getGoodsType()==2){
                Integer[] goodsValue = coupon.getGoodsValue();
                goodsValueList.addAll(Arrays.asList(goodsValue));
                for (Integer goodsId : goodsIdsCart) {
                    if (goodsValueList.contains(goodsId)){
                        couponList.add(coupon);
                    }
                }
            }

        }
        //此时已经得到了对应的商品，才能领到什么样子的优惠券
        //现在将优惠券的信息封装，传给前端JSON
        //将List<WxCouponCartVO>里面的name，desc，tag，min，discount等7个字段，用List<Coupon>的数据字段填满
        //因为购物车里面的优惠券必须是已经领取了的，在receive里面已经设置了startTime和EndTime，肯定有值，这里不应该报JAVA.NULL.POINTER exception
        for (Coupon coupon : couponList) {
            WxCouponCartVO vo = new WxCouponCartVO();
            for (CouponUser couponUser : couponUsers) {
                Integer cid = couponUser.getCouponId();
                Integer id = coupon.getId();
                if(!cid.equals(id)){
                    continue;
                }
                vo.setName(coupon.getName());
                vo.setDesc(coupon.getDesc());
                vo.setMin(coupon.getMin());
                vo.setDiscount(coupon.getDiscount());
                vo.setId(id);
                vo.setCid(cid);
                vo.setStartTime(couponUser.getStartTime());
                vo.setEndTime(couponUser.getEndTime());
                if (!StringUtils.isEmpty(coupon.getTag())){
                    vo.setTag(coupon.getTag());
                }
                break;
            }
            couponCartList.add(vo);
        }
        long total = couponCartList.size();
        BaseData data = BaseData.list(couponCartList, total);
        data.setLimit((int) total);
        data.setPage(1);
        data.setPages(1);
        return data;
    }

    @Override
    public int receiveCoupon(Integer couponId) {
        CouponExample example = new CouponExample();
        CouponExample.Criteria couponCriteria = example.createCriteria();
        couponCriteria.andDeletedEqualTo(false).andTotalGreaterThanOrEqualTo(0);
        couponCriteria.andIdEqualTo(couponId);
        List<Coupon> couponList = couponMapper.selectByExample(example);
        //因为couponId是唯一的，所以这样list只有一个coupon
        Coupon coupon = couponList.get(0);
        //在数据库里更新coupon的limit-1
        coupon.setLimit((short) (coupon.getLimit()-1));
        if (coupon.getStartTime()==null || coupon.getEndTime()==null){
            coupon.setStartTime(new Date());
            Date startTime = coupon.getStartTime();
            Date end =new Date(startTime.getTime()+coupon.getDays()) ;
            coupon.setEndTime(end);
        }
        //将领的优惠券插入coupon-user数据库里，可以得到用户都领了什么优惠券
        Integer userId = GetSubject.getUserId();
        CouponUser couponUser = new CouponUser();
        couponUser.setCouponId(couponId);
        couponUser.setUserId(userId);
        couponUser.setStatus(coupon.getStatus());
        couponUser.setStartTime(coupon.getStartTime());
        couponUser.setEndTime(coupon.getEndTime());
        couponUser.setDeleted(coupon.getDeleted());
        //TODO 这里需要在coupon-usesr表里插入哪个订单order_id,使用时间used_time
        int i =couponUserMapper.insertSelective(couponUser);
        int rows = couponMapper.updateByPrimaryKeySelective(coupon);
        return rows+i;
    }

    @SneakyThrows
    @Override
    public int exchangeCoupon(String code) {
        CouponExample example = new CouponExample();
        CouponExample.Criteria criteria = example.createCriteria();
        criteria.andDeletedEqualTo(false).andStatusEqualTo((short) 0);
        criteria.andCodeEqualTo(code);
        //用兑换码查询出来的没有被删除，没有过期or下架的,是正常可用的优惠券
        List<Coupon> couponList = couponMapper.selectByExample(example);
        if (couponList.size()==0){
            return 0;
        }
        Coupon coupon = couponList.get(0);
        if (coupon.getLimit()<0){
            throw new Param602Exception("优惠券已经兑换过！");
        }
        coupon.setLimit((short) -1);
        coupon.setStatus((short) 1);
        int rows = couponMapper.updateByPrimaryKeySelective(coupon);
        return rows;
    }
}